From: kfraser@localhost.localdomain Date: Fri, 29 Sep 2006 13:20:52 +0000 (+0100) Subject: [LINUX] Make evtchn device use a dynamic minor number. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~15622^2~23^2 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks://%22Dat/%22http:/www.example.com/cgi/%22https:/%22bookmarks:/%22Dat?a=commitdiff_plain;h=ada55182d201bf569fc547bbfe1b5d36c23711fa;p=xen.git [LINUX] Make evtchn device use a dynamic minor number. Also update the code in tools to create the device node if udev fails. The tools now read the sysfs system to find the minor number needed. Original patch from Steven Rostedt Signed-off-by: Keir Fraser --- diff --git a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c index 76bfab82e6..32f8de5bff 100644 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c @@ -419,10 +419,9 @@ static struct file_operations evtchn_fops = { }; static struct miscdevice evtchn_miscdev = { - .minor = EVTCHN_MINOR, + .minor = MISC_DYNAMIC_MINOR, .name = "evtchn", .fops = &evtchn_fops, - .devfs_name = "misc/evtchn", }; static int __init evtchn_init(void) diff --git a/linux-2.6-xen-sparse/include/xen/public/evtchn.h b/linux-2.6-xen-sparse/include/xen/public/evtchn.h index 99e2948240..938d4da2bd 100644 --- a/linux-2.6-xen-sparse/include/xen/public/evtchn.h +++ b/linux-2.6-xen-sparse/include/xen/public/evtchn.h @@ -33,9 +33,6 @@ #ifndef __LINUX_PUBLIC_EVTCHN_H__ #define __LINUX_PUBLIC_EVTCHN_H__ -/* /dev/xen/evtchn resides at device number major=10, minor=201 */ -#define EVTCHN_MINOR 201 - /* * Bind a fresh port to VIRQ @virq. * Return allocated port. diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c index c803b9a827..a70307a542 100644 --- a/tools/libxc/xc_linux.c +++ b/tools/libxc/xc_linux.c @@ -133,27 +133,95 @@ int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall) (unsigned long)hypercall); } +#define MTAB "/proc/mounts" +#define MAX_PATH 255 +#define _STR(x) #x +#define STR(x) _STR(x) + +static int find_sysfsdir(char *sysfsdir) +{ + FILE *fp; + char type[MAX_PATH + 1]; + + if ( (fp = fopen(MTAB, "r")) == NULL ) + return -1; + + while ( fscanf(fp, "%*s %" + STR(MAX_PATH) + "s %" + STR(MAX_PATH) + "s %*s %*d %*d\n", + sysfsdir, type) == 2 ) + { + if ( strncmp(type, "sysfs", 5) == 0 ) + break; + } + + fclose(fp); + + return ((strncmp(type, "sysfs", 5) == 0) ? 0 : -1); +} + +int xc_find_device_number(const char *name) +{ + FILE *fp; + int i, major, minor; + char sysfsdir[MAX_PATH + 1]; + static char *classlist[] = { "xen", "misc" }; + + for ( i = 0; i < (sizeof(classlist) / sizeof(classlist[0])); i++ ) + { + if ( find_sysfsdir(sysfsdir) < 0 ) + goto not_found; + + /* /class///dev */ + strncat(sysfsdir, "/class/", MAX_PATH); + strncat(sysfsdir, classlist[i], MAX_PATH); + strncat(sysfsdir, "/", MAX_PATH); + strncat(sysfsdir, name, MAX_PATH); + strncat(sysfsdir, "/dev", MAX_PATH); + + if ( (fp = fopen(sysfsdir, "r")) != NULL ) + goto found; + } + + not_found: + errno = -ENOENT; + return -1; + + found: + if ( fscanf(fp, "%d:%d", &major, &minor) != 2 ) + { + fclose(fp); + goto not_found; + } + + fclose(fp); + + return makedev(major, minor); +} + #define EVTCHN_DEV_NAME "/dev/xen/evtchn" -#define EVTCHN_DEV_MAJOR 10 -#define EVTCHN_DEV_MINOR 201 int xc_evtchn_open(void) { struct stat st; int fd; + int devnum; + + devnum = xc_find_device_number("evtchn"); /* Make sure any existing device file links to correct device. */ - if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || - (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR))) + if ( (lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) || + (st.st_rdev != devnum) ) (void)unlink(EVTCHN_DEV_NAME); -reopen: + reopen: if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 ) { if ( (errno == ENOENT) && ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) && - (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, - makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) ) + (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600, devnum) == 0) ) goto reopen; PERROR("Could not open event channel interface"); diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 0a5cfadd3d..d74c1c8c27 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -91,6 +91,16 @@ int xc_interface_open(void); */ int xc_interface_close(int xc_handle); +/* + * KERNEL INTERFACES + */ + +/* + * Resolve a kernel device name (e.g., "evtchn", "blktap0") into a kernel + * device number. Returns -1 on error (and sets errno). + */ +int xc_find_device_number(const char *name); + /* * DOMAIN DEBUGGING FUNCTIONS */